package top.dugou.dugou_sso_server.controller;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import top.dugou.dugou_sso_server.common.Encryption;
import top.dugou.dugou_sso_server.common.JuheMessage;
import top.dugou.dugou_sso_server.common.RandomNum;
import top.dugou.dugou_sso_server.common.Result;
import top.dugou.dugou_sso_server.entity.User;
import top.dugou.dugou_sso_server.service.UserService;
import top.dugou.dugou_sso_server.utils.RedisUtil;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {

    protected static final Logger logger = LoggerFactory.getLogger(UserController.class);
    @Resource
    private UserService userService;

    @Resource
    private RedisUtil redisUtil;

    @Value("${juheApi.tplID}")
    private String tplid;
    @Value("${juheApi.key}")
    private String key;

    /**
     * 添加用户
     * @param user
     * @return
     */
    @ApiOperation(value = "添加用户信息")
    @ApiResponses({
            @ApiResponse(code = 201,message = "添加成功"),
            @ApiResponse(code = 500,message = "添加失败")
    })
    @PostMapping(value = "/adduser")
    @ResponseBody
    public Map adduser(@RequestBody @ApiParam(value = "添加用户的信息",required = true) User user){
        int res = 0;
        if(user.getPassword() != null){
            try {
                user.setPassword(Encryption.md5(user.getPassword()));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
        user.setCreated(new Date());
        user.setUpdate(new Date());
        res = userService.addUser(user);
        if(res > 0){
            return  Result.instance("201","添加成功").toJsonMap();
        }else{
            return  Result.instance("500","添加失败").toJsonMap();
        }
    }

    /**
     * 删除用户信息
     * @param id
     * @return
     */
    @ApiOperation(value="删除用户信息")
    @ApiResponses({
            @ApiResponse(code = 204,message = "删除成功"),
            @ApiResponse(code = 500,message = "删除失败")
    })
    @RequestMapping(value = "/deluser/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public Map delUser(@PathVariable("id") @ApiParam(value = "用户主键ID",required = true) Long id){
        int res = 0;
        res = userService.delUser(id);
        if(res > 0){
            return  Result.instance("204","删除成功").toJsonMap();
        }else{
            return  Result.instance("500","删除失败").toJsonMap();
        }
    }

    /**
     * 修改用户信息，必须传入主键ID
     * @param user
     * @return
     */
    @ApiOperation(value = "更新用户信息")
    @ApiResponses({
            @ApiResponse(code = 205,message = "修改成功"),
            @ApiResponse(code = 500,message = "修改失败")
    })
    @RequestMapping(value = "/update",method = RequestMethod.PUT)
    @ResponseBody
    public Map update(@RequestBody @ApiParam(value = "要更新的信息，必须传入主键ID") User user){
        int res = 0;
        if(user.getPassword() != null){
            try {
                user.setPassword(Encryption.md5(user.getPassword()));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
        user.setUpdate(new Date());
        res = userService.updateUser(user);
        if(res > 0){
            return  Result.instance("205","修改成功").toJsonMap();
        }else{
            return  Result.instance("500","修改失败").toJsonMap();
        }
    }

    /**
     * 查询单个用户信息 传入主键ID
     * @param id
     * @return
     */
    @ApiOperation(value="查询单个用户信息，传入主键")
    @ApiResponses({
            @ApiResponse(code = 200,message = "查询成功"),
            @ApiResponse(code = 500,message = "查询失败")
    })
    @RequestMapping(value = "/find/{id}",method = RequestMethod.GET)
    @ResponseBody
    public Map findById(@PathVariable("id") @ApiParam(value = "/用户主键ID")  Long id){
        User user = new User();
        user = userService.findById(id);
        if(user != null){
            return  Result.<User>instance("200","查询成功",user).toJsonMap();
        }else{
            return  Result.<User>instance("500","查询失败",user).toJsonMap();
        }
    }

    /**
     * 条件查询，
     * @param user
     * @return
     */
    @ApiOperation(value="通过用户信息查询用户")
    @ApiResponses({
            @ApiResponse(code = 200,message = "查询成功"),
            @ApiResponse(code = 500,message = "查询失败")
    })
    @RequestMapping(value = "/select",method = RequestMethod.POST)
    @ResponseBody
    public Map selectByCondition(@RequestBody @ApiParam(value = "用户的部分信息",required = true) User user){
        List<User> list = userService.selectByCondition(user);
        if(list.size() > 0){
            return  Result.<List<User>>instance("200","查询成功",list).toJsonMap();
        }else{
            return  Result.<List<User>>instance("500","查询失败",list).toJsonMap();
        }
    }


    /**
     * 检查该手机号是否已经注册
     * @param phone
     * @return
     */
    @ApiOperation(value="检查手机号是否已经注册")
    @ApiResponses({
            @ApiResponse(code = 204,message = "未注册"),
            @ApiResponse(code = 200,message = "已注册")
    })
    @RequestMapping(value = "/auth/checkPhone/{phone}",method = RequestMethod.GET)
    @ResponseBody
    public Map findByPhone(@PathVariable("phone") @ApiParam(value = "手机号码（用户名）",required = true) String phone){
        User user = new User();
        user.setUsername(phone);
        List<User> list = userService.selectByCondition(user);

        if(list.size() == 0){
            return  Result.instance("204","未注册").toJsonMap();
        }else{
            return  Result.instance("200","已注册").toJsonMap();
        }
    }

    /**
     * 发送短信验证码
     * @param phone
     * @return
     */
    @ApiOperation(value="发送手机号验证码")
    @ApiResponses({
            @ApiResponse(code = 204,message = "发送并存储成功"),
            @ApiResponse(code = 501,message = "发送失败,服务不可用"),
            @ApiResponse(code = 500,message = "发送失败,发送但Redis存储失败")
    })
    @RequestMapping(value = "/auth/postcode/{phone}",method = RequestMethod.GET)
    @ResponseBody
    public Map postMessageCode(@PathVariable("phone") @ApiParam(value = "手机号码",required = true) String phone){
        String code = RandomNum.GetRandomString(100000,999999);

        //发送验证码
        Map<String,Object> result = JuheMessage.mobileQuery(phone,tplid,"#code#="+code,key);

        if((int)result.get("statusCode") == 200){
            if (redisUtil.set(phone,code,60*2)){
                result = Result.instance("204","发送并存储成功").toJsonMap();
            }  else{
                result = Result.instance("500","发送但Redis存储失败").toJsonMap();
            }
        } else{
            result = Result.instance("501","发送失败:"+result.get("message").toString()).toJsonMap();
        }

        return result;
    }

    /**
     * 用户注册
     * @param phone
     * @param pwd
     * @param code
     * @return
     */
   @ApiOperation(value = "用户注册")
   @ApiResponses({
           @ApiResponse(code = 201,message = "注册成功"),
           @ApiResponse(code = 406,message = "验证失败"),
           @ApiResponse(code = 500,message = "注册失败")
   })
   @RequestMapping(value = "/auth/register/{phone}/{pwd}/{code}",method = RequestMethod.POST)
   @ResponseBody
    public Map register(
      @PathVariable(value = "phone",required = true) @ApiParam(value = "手机号（用户名）",required = true) String phone,
      @PathVariable(value = "pwd",required = true) @ApiParam(value = "密码",required = true) String pwd,
      @PathVariable(value = "code",required = true) @ApiParam(value = "手机号验证码",required = true) String code
    ){
       if(!redisUtil.hasKey(phone)){
           //redis里面没有验证码
           return  Result.instance("406","验证码失效").toJsonMap();
       }else{
           //redis里面存在验证码
           String redisCode =  redisUtil.get(phone).toString();
           if(!redisCode.equals(code)){
               //输入的验证码和redis 里面存储的不一致
               return  Result.instance("406","验证码不正确").toJsonMap();
           } else{
               //验证码一致
               User user = new User();
               int res = 0;
               user.setUsername(phone);
               if(pwd != null && pwd.length() != 0){
                   try {
                       user.setPassword(Encryption.md5(pwd));
                   } catch (NoSuchAlgorithmException e) {
                       e.printStackTrace();
                   }
               }
               user.setCreated(new Date());
               user.setUpdate(new Date());
               res = userService.addUser(user);
               if(res > 0){
                   return  Result.instance("201","注册成功").toJsonMap();
               }else{
                   return  Result.instance("500","注册失败").toJsonMap();
               }
           }
       }
    }


    /**
     * 根据时间戳，获取图片验证码，并存入redis里面
     * 存储为key为时间戳，value为imgcode
     * @param timetamp
     * @return
     */
    @ApiOperation(value = "根据时间戳，获取图片验证码")
    @ApiResponses({
            @ApiResponse(code = 201,message = "图片验证码获取成功"),
            @ApiResponse(code = 500,message = "图片验证码获取失败")
    })
    @RequestMapping(value = "/auth/getImgCode/{timetamp}",method = RequestMethod.GET)
    @ResponseBody
    public Map getImgCode(@PathVariable("timetamp") @ApiParam(value = "时间戳",required = true) String timetamp){
       String imgCode = RandomNum.GetRandomString(1000 , 9999);
        if(redisUtil.set(timetamp, imgCode,60*5)){
            return  Result.<String>instance("201","图片验证码获取成功",imgCode).toJsonMap();
        }else{
            return  Result.instance("500","图片验证码获取失败").toJsonMap();
        }
    }

    /**
     * 用户登录
     * @param phone
     * @param password
     * @param timetamp
     * @param imgCode
     * @return
     */
    @ApiOperation(value = "用户登录")
    @ApiResponses({
            @ApiResponse(code = 200,message = "登录成功"),
            @ApiResponse(code = 406,message = "验证失败"),
            @ApiResponse(code = 500,message = "登录失败")
    })
    @RequestMapping(value = "/auth/login/{phone}/{password}/{timetamp}/{imgCode}",method = RequestMethod.POST)
    @ResponseBody
    public Map login(
      @PathVariable(value = "phone",required = true)   @ApiParam(value = "手机号（用户名）",required = true)  String phone,
      @PathVariable(value = "password",required = true)   @ApiParam(value = "密码",required = true)  String password,
      @PathVariable(value = "timetamp",required = true)   @ApiParam(value = "时间戳",required = true)  String timetamp,
      @PathVariable(value = "imgCode",required = true)   @ApiParam(value = "图片验证码",required = true)  String imgCode
    ){
        if(!redisUtil.hasKey(timetamp)){
            //redis里面没有验证码失效
            return  Result.instance("406","验证码失效").toJsonMap();
        }else{
            String code = redisUtil.get(timetamp).toString();
            if(!imgCode.equals(code)){
                //验证码不一致
                return  Result.instance("406","验证码不正确").toJsonMap();
            }else{
                User user = new User();
                user.setUsername(phone);
                try {
                    user.setPassword(Encryption.md5(password));
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                }

                List<User> list = userService.selectByCondition(user);
                if(list.size() > 0){
                    Map<String,Object> res = new HashMap<>();
                    User user1 = list.get(0);
                    res.put("userinfo",user1);
                    String key = user1.getUsername()+String.valueOf(System.currentTimeMillis());
                    try {
                        String token =Encryption.md5(key);
                        //登录token  存放着在redis一周
                        if(redisUtil.set(token,user1.getId(),60*60*24*7)){
                            res.put("token",token);
                            return  Result.<Map<String,Object>>instance("200","登录成功",res).toJsonMap();
                        }else{
                            return  Result.instance("500","登录失败").toJsonMap();
                        }
                    } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                    }

                }else{
                    return  Result.instance("406","密码或手机号不正确").toJsonMap();
                }
            }
        }
        return Result.instance("500","登录失败").toJsonMap();
    }

    /**
     * 退出登录
     * @param token
     * @return
     */
    @ApiOperation(value = "用户退出")
    @ApiResponses({
            @ApiResponse(code = 204,message = "退出登录成功"),
            @ApiResponse(code = 205,message = "已退出"),
            @ApiResponse(code = 500,message = "退出登录失败")
    })
    @RequestMapping(value = "/auth/loginout",method = RequestMethod.GET)
    public Map loginout(@RequestParam(value = "token",required = true) @ApiParam(value = "口令token",required = true) String token){

        if(redisUtil.hasKey(token)){
            if(redisUtil.expire(token,1)){
                return Result.instance("204","退出登录成功").toJsonMap();
            }else{
                return Result.instance("500","退出登录失败").toJsonMap();
            }
        }else{
            return Result.instance("205","已退出").toJsonMap();
        }

    }

    /**
     * 忘记密码，修改密码
     * @param phone
     * @param pwd
     * @param code
     * @return
     */
    @ApiOperation(value = "忘记密码，修改密码")
    @ApiResponses({
            @ApiResponse(code = 204,message = "注册成功"),
            @ApiResponse(code = 406,message = "验证失败"),
            @ApiResponse(code = 500,message = "注册失败")
    })
    @RequestMapping(value = "/auth/forget/{phone}/{pwd}/{code}",method = RequestMethod.POST)
    @ResponseBody
    public Map forgetPwd (
            @PathVariable(value = "phone",required = true) @ApiParam(value = "手机号（用户名）",required = true) String phone,
            @PathVariable(value = "pwd",required = true) @ApiParam(value = "密码",required = true) String pwd,
            @PathVariable(value = "code",required = true) @ApiParam(value = "手机号验证码",required = true) String code
    ){
        if(!redisUtil.hasKey(phone)){
            //redis里面没有验证码
            return  Result.instance("406","验证码失效").toJsonMap();
        }else{
            //redis里面存在验证码
            String redisCode =  redisUtil.get(phone).toString();
            if(!redisCode.equals(code)){
                //输入的验证码和redis 里面存储的不一致
                return  Result.instance("406","验证码不正确").toJsonMap();
            } else{
                //验证码一致
                User user = new User();
                int res = 0;
                user.setUsername(phone);

                user = userService.selectByCondition(user).get(0);

                if(pwd != null && pwd.length() != 0){
                    try {
                        user.setPassword(Encryption.md5(pwd));
                    } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                    }
                }

                user.setUpdate(new Date());
                res = userService.updateUser(user);
                if(res > 0){
                    return  Result.instance("204","修改成功").toJsonMap();
                }else{
                    return  Result.instance("500","修改失败").toJsonMap();
                }
            }
        }
    }
}
